package org.smart4j.framework.helper;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.smart4j.framework.annotation.Action;
import org.smart4j.framework.bean.Handler;
import org.smart4j.framework.bean.Request;
import org.smart4j.framework.util.ArrayUtil;
import org.smart4j.framework.util.CollectionUtil;

/**
 * 控制器助手类：
 * 这个类通过扫描类集合中Controller类中每个类的方法Action注解来构造请求和具体方法之间的映射关系，
 * 当有请求到来的时候就可以通过请求方法和路径来找出对应类以及类上面的方法了
 *
 *
 */
public final class ControllerHelper {

    private static final Map<Request, Handler> ACTION_MAP = new HashMap<Request, Handler>();

    static {
        // 获取所有带有Controller注解的类
        Set<Class<?>> controllerClassSet = ClassHelper.getControllerClassSet();
        if (CollectionUtil.isNotEmpty(controllerClassSet)) {
            // 循环处理这些类
            for (Class<?> controllerClass : controllerClassSet) {
                // 获取类中的方法
                Method[] methods = controllerClass.getDeclaredMethods();
                if (ArrayUtil.isNotEmpty(methods)) {
                    // 循环处理这些方法
                    for (Method method : methods) {
                        // 处理带有Action注解的方法
                        if (method.isAnnotationPresent(Action.class)) {
                            // 获取Action注解内容
                            Action action = method.getAnnotation(Action.class);
                            String mapping = action.value();
                            if (mapping.matches("\\w+:/\\w*")) {
                                // 通过【:】拆分注解
                                // @Action("get:/customer")
                                String[] array = mapping.split(":");
                                // 判断当前的Action参数是不是符合规定
                                if (ArrayUtil.isNotEmpty(array) && array.length == 2) {
                                    // 解析请求方法类型
                                    String requestMethod = array[0];
                                    // 解析请求的路径
                                    String requestPath = array[1];
                                    // 构造请求的对象：方法类型+请求路径
                                    Request request = new Request(requestMethod, requestPath);
                                    // 构造处理对象：类+方法
                                    Handler handler = new Handler(controllerClass, method);
                                    // 构造请求和处理对象之间的关系
                                    ACTION_MAP.put(request, handler);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 获取 Handler
     */
    public static Handler getHandler(String requestMethod, String requestPath) {
        Request request = new Request(requestMethod, requestPath);
        return ACTION_MAP.get(request);
    }
}
